package it.marco.test.controller;

import it.marco.test.annotations.Authorizable;
import it.marco.test.dm.CustomAuthorization;
import it.marco.test.dm.GruppoAutorizzazioni;
import it.marco.test.dm.Role;
import it.marco.test.service.RoleService;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.AccessControlEntry;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.AclService;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

@Controller
@RequestMapping(value="/admin/authorization")
@SessionAttributes({"authorization","listaAuth","listaAuthRuolo"})
public class AuthorizationController {
	
	@Autowired
	private AclService/*<User, String>*/ serv;
	
	@Autowired
	private RoleService roleServ;
//	@Autowired
//	private TestService s;
//	
//	@Autowired
//	private Validator validator;
//	
//	public void setValidator(Validator validator) {  
//        this.validator = validator;  
//	}  
	
	@RequestMapping(method=RequestMethod.GET)
	public String getListaRuoli(ModelMap model, HttpServletRequest request){
		List<Role> ruoli =  roleServ.findAll();
//		if (ruoli.size()>0){
//			this.getListaAuth(model, ruoli.get(1).getCodRuolo(), request);
//		}
		Map<String,List<CustomAuthorization>> lca = this.getListaAuth(model, request);
		if (ruoli.size()>0){
			GruppoAutorizzazioni ga = new GruppoAutorizzazioni();
			ga.setLista(lca.get(ruoli.get(0).getCodRuolo()));
			model.addAttribute("listaAuthRuolo", ga);
		}
		model.addAttribute("listaAuth", lca);
		model.addAttribute("ruoli", ruoli);
		model.addAttribute("test", "CIAO");
		return "sceltaRuolo";
	}
	
	public Map<String,List<CustomAuthorization>>  getListaAuth(ModelMap model, HttpServletRequest request){
		Map<String, Object> listaBean = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext()).getBeansWithAnnotation(Authorizable.class);
		List<ObjectIdentity> listaId = new LinkedList<ObjectIdentity>();
		for (Object b : listaBean.values()) {
			ObjectIdentityImpl oi = new ObjectIdentityImpl(b);
			listaId.add(oi);
		}
		List<Sid> listaSid = new LinkedList<Sid>();
//		Sid s = new GrantedAuthoritySid(ruolo);
//		listaSid.add(s);
		Map<ObjectIdentity, Acl> listaAcl =  serv.readAclsById(listaId); //, listaSid);
		
		Map<String,List<CustomAuthorization>> lca = new HashMap<String,List<CustomAuthorization>>();
		//List<AccessControlEntry> lista =  serv.
		//List<User> lp = serv.findAll();
		//((GrantedAuthority)listaAcl.values().iterator().next().getEntries().iterator().next().getSid()).
		Iterator<Acl> iter = listaAcl.values().iterator();
		while (iter.hasNext()){
			Acl a = iter.next();
			
			Iterator<AccessControlEntry> it2 = a.getEntries().iterator();
			while (it2.hasNext()){
				AccessControlEntry ace = it2.next();
				CustomAuthorization ca = new CustomAuthorization();
				ca.setClassName(a.getObjectIdentity().getType());
				ca.setRole(((GrantedAuthoritySid)ace.getSid()).getGrantedAuthority());
				if (!lca.containsKey(ca.getRole())){
					lca.put(ca.getRole(), new LinkedList<CustomAuthorization>());
				}
				List<CustomAuthorization> l = lca.get(ca.getRole());
				if (!l.contains(ca)){
					l.add(ca);
				}
				ca = l.get(l.indexOf(ca));
				int perm = ace.getPermission().getMask();
				if (ace.getPermission().equals(BasePermission.WRITE)){
					ca.setWrite(1);
				}else if (ace.getPermission().equals(BasePermission.ADMINISTRATION)){
					ca.setAdmin(1);
				}else if (ace.getPermission().equals(BasePermission.CREATE)){
					ca.setCreate(1);
				}else if (ace.getPermission().equals(BasePermission.DELETE)){
					ca.setDelete(1);
				}else if (ace.getPermission().equals(BasePermission.READ)){
					ca.setRead(1);
				}
			}
		}
		//model.addAttribute("listaAuth",lca);
		
		
		return lca;
//		return new ModelAndView("index","test", "Ciao a tutti");
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(method=RequestMethod.POST)
	public String refreshAuth(@RequestParam("ruolo") String ruolo,ModelMap model, HttpServletRequest request ){
		//this.getListaAuth(model, ruolo, request);
		//model.addAttribute("listaAuth",new LinkedList<String>());
		Map<String,List<CustomAuthorization>> a = (Map<String,List<CustomAuthorization>>) model.get("listaAuth");
		GruppoAutorizzazioni ga = new GruppoAutorizzazioni();
		ga.setLista(a.get(ruolo));
		model.addAttribute("listaAuthRuolo", ga);
		model.addAttribute("test", "ADDIO");
		return "listaAjax";
	}
	
	
}
